package cn.cytong.nk0713.crypto;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import java.security.Security;
import java.security.spec.KeySpec;

public class DESUtil {

    static String DES = "DES/ECB/NOPADDING";
    static String TriDes = "DESede/ECB/PKCS7PADDING";

    public static byte[] des_crypt(byte key[], byte data[]) {

        try {
            KeySpec ks = new DESKeySpec(key);
            SecretKeyFactory kf = SecretKeyFactory.getInstance("DES");
            SecretKey ky = kf.generateSecret(ks);

            Cipher c = Cipher.getInstance(DES);
            c.init(Cipher.ENCRYPT_MODE, ky);
            return c.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static byte[] des_decrypt(byte key[], byte data[]) {

        try {
            KeySpec ks = new DESKeySpec(key);
            SecretKeyFactory kf = SecretKeyFactory.getInstance("DES");
            SecretKey ky = kf.generateSecret(ks);

            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//添加PKCS7Padding支持
            Cipher c = Cipher.getInstance(DES);
            c.init(Cipher.DECRYPT_MODE, ky);
            return c.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static byte[] trides_crypt(byte key[], byte data[]) {
        try {
            byte[] k = new byte[24];
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//添加PKCS7Padding支持
//            int len = data.length;
//            if (data.length % 8 != 0) {
//                len = data.length - data.length % 8 + 8;
//            }
//            byte[] needData = null;
//            if (len != 0)
//                needData = new byte[len];
//
//            for (int i = 0; i < len; i++) {
//                needData[i] = 0x00;
//            }
//
//            System.arraycopy(data, 0, needData, 0, data.length);

            if (key.length == 16) {
                System.arraycopy(key, 0, k, 0, key.length);
                System.arraycopy(key, 0, k, 16, 8);
            } else {
                System.arraycopy(key, 0, k, 0, 24);
            }

            KeySpec ks = new DESedeKeySpec(k);
            SecretKeyFactory kf = SecretKeyFactory.getInstance("DESede");
            SecretKey ky = kf.generateSecret(ks);

            Cipher c = Cipher.getInstance(TriDes);
            c.init(Cipher.ENCRYPT_MODE, ky);
//            return c.doFinal(needData);
            return c.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    public static byte[] trides_decrypt(byte key[], byte data[]) {
        try {
            byte[] k = new byte[24];
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//添加PKCS7Padding支持
//            int len = data.length;
//            if (data.length % 8 != 0) {
//                len = data.length - data.length % 8 + 8;
//            }
//            byte[] needData = null;
//            if (len != 0)
//                needData = new byte[len];
//
//            for (int i = 0; i < len; i++) {
//                needData[i] = 0x00;
//            }
//
//            System.arraycopy(data, 0, needData, 0, data.length);

            if (key.length == 16) {
                System.arraycopy(key, 0, k, 0, key.length);
                System.arraycopy(key, 0, k, 16, 8);
            } else {
                System.arraycopy(key, 0, k, 0, 24);
            }
            KeySpec ks = new DESedeKeySpec(k);
            SecretKeyFactory kf = SecretKeyFactory.getInstance("DESede");
            SecretKey ky = kf.generateSecret(ks);

            Cipher c = Cipher.getInstance(TriDes);
            c.init(Cipher.DECRYPT_MODE, ky);
//            return c.doFinal(needData);
            return c.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    public static void main(String[] args) {

        byte k1[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0x88};
        byte k2[] = {(byte) 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
        byte k24[] = new byte[24];
        System.arraycopy(k1, 0, k24, 0, 8);
        System.arraycopy(k2, 0, k24, 8, 8);
        System.arraycopy(k1, 0, k24, 16, 8);

        byte data[] = //
                hexToBytes("00000000" + "00000000" + "00000000" + "00000000"
                        + "0000c619" + "f4fb7bde" + "51309100" + "00110000"
                        + "00000000" + "00000000" + "00000000" + "00000000"
                        + "00000000" + "00000000" + "00000000" + "00000000"
                        + "00000000" + "00000000" + "00000000" + "00000000"
                        + "00000000" + "00000000" + "00000000" + "00000000"
                        + "00000000" + "00000000" + "00000000" + "00000000"
                        + "00000000" + "00000000" + "00000000" + "00000000");

        // data = new byte[8];
        // byte des_crypt[] = des_crypt(k1, data);
        // byte des_descrypt[] = des_decrypt(k2, des_crypt);
        // byte result[] = des_crypt(k1, des_descrypt);

        byte result[] = trides_crypt(k24, data);
        // byte origin[] = trides_decrypt(k24, result);

        System.out.println("Result = " + result);
    }

    public static byte[] hexToBytes(String str) {
        if (str == null) {
            return null;
        } else if (str.length() < 2) {
            return null;
        } else {
            int len = str.length() / 2;
            byte[] buffer = new byte[len];
            for (int i = 0; i < len; i++) {
                buffer[i] = (byte) Integer.parseInt(str.substring(i * 2,
                        i * 2 + 2), 16);
            }
            return buffer;
        }
    }
}
